package com.zwh.gittool;

import cn.hutool.core.io.FileUtil;
import lombok.SneakyThrows;
import org.apache.commons.compress.utils.Lists;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.RenameDetector;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.filter.CommitTimeRevFilter;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.treewalk.TreeWalk;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author 郑文豪
 */
public class JGitLogs {
    static String path = "D:\\a_work\\mind_cdp";
    static String destPath = "C:\\Users\\郑文豪\\Desktop\\新建文件夹 (8)";
    static String configPath = destPath + "\\config\\config.txt";
    static String startDate = "2024-01-23 00:00:00";
    static String endDate = "2025-11-01";
    static Git git = null;

    public static void main(String[] args) throws Exception {
        FileUtil.del(destPath);
        File repoDir = new File(path);

        // 构建仓库
        Repository repository = new FileRepositoryBuilder().findGitDir(repoDir).build();
        git = new Git(repository);
        ArrayList<String> gitVersion = getGitVersion();
        List<String> paths = Lists.newArrayList();
        for (String v : gitVersion) {
            List<DiffEntry> lists = getCommitLogList(v);
            for (DiffEntry d : lists) {
                String oldPath = d.getOldPath();
                String newPath = d.getNewPath();
                if (paths.contains(oldPath) || paths.contains(newPath)) {
                    continue;
                }

                if (oldPath != null && !"/dev/null".equals(oldPath)) {
                    paths.add(oldPath);
                }
                if (newPath != null && !"/dev/null".equals(newPath)) {
                    paths.add(newPath);
                }

            }
        }
        List<String> dels = Lists.newArrayList();
        for (String s : paths) {
            File src = new File(path + File.separatorChar + s);
            if (src.exists()) {
                File dest = new File(destPath + File.separatorChar + s);
                FileUtil.copy(src, dest, true);
            } else {
                dels.add(s);
            }
        }
        FileUtil.writeUtf8Lines(dels, new File(configPath));

    }

    /**
     * @方法简介: 获取所有的版本号与版本号对应的时间戳
     */
    @SneakyThrows
    public static ArrayList<String> getGitVersion() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        Iterable<RevCommit> logIterable = git.log().setRevFilter(CommitTimeRevFilter.between(dateFormat.parse(startDate), dateFormat.parse(endDate))).call();
        Iterator<RevCommit> logIterator = logIterable.iterator();//获取所有版本号的迭代器

        if (logIterator == null) {
            throw new RuntimeException("该项目暂无日志记录");
        }
        ArrayList<String> list = new ArrayList<>();
        while (logIterator.hasNext()) {
            RevCommit commit = logIterator.next();
//            Date commitDate = commit.getAuthorIdent().getWhen();     //提交时间
            String commitID = commit.getName();    //提交的版本号（之后根据这个版本号去获取对应的详情记录）
            list.add(commitID);
        }
        return list;
    }

    /**
     * @方法简介 :根据指定版本号获取版本号下面的详情记录
     */
    @SneakyThrows
    public static List<DiffEntry> getCommitLogList(String revision) {
        // 通过git获取项目库
        Repository repository = git.getRepository();
        // 根据所需要查询的版本号查新ObjectId
        ObjectId objId = repository.resolve(revision);

        //根据版本号获取指定的详细记录
        Iterable<RevCommit> allCommitsLater = git.log().add(objId).call();
        if (allCommitsLater == null) {
            throw new Exception("该提交版本下无当前查询用户的提交记录");
        }
        Iterator<RevCommit> iter = allCommitsLater.iterator();
        RevCommit commit = iter.next();//提交对象

        // 给存储库创建一个树的遍历器
        TreeWalk tw = new TreeWalk(repository);
        // 将当前commit的树放入树的遍历器中
        tw.addTree(commit.getTree());

        commit = iter.next();
        if (commit != null) {
            tw.addTree(commit.getTree());
        } else {
            return null;
        }

        tw.setRecursive(true);
        RenameDetector rd = new RenameDetector(repository);
        rd.addAll(DiffEntry.scan(tw));
        //获取到详细记录结果集    在这里就能获取到一个版本号对应的所有提交记录（详情！！！）
        return rd.compute();
    }

}
